/*
 * $Id: MutexSync.java 9 2006-03-08 10:21:59Z wjx $
 */
package com.someok.utils;

/**
 * The very same Mutex, with lockTry() method added. This method locks a
 * mutex if mutex is currently unlocked and returns true. If mutex was
 * previously locked, it will not wait for its releasing: instead, it will
 * just return false.
 *
 * Since both lock() and lockTry() methods are synchronized, lockTry() can
 * not returns the faked 'true' which indicates that mutex was availiable and
 * locked, while this is not true and while another thread has meanwhile
 * locked the mutex. But, the opposite situation can happend: lockTry() may
 * return faked 'false' which indicated that mutex is in use, while meanwhile
 * another thread that has a lock may release it. However, this situations
 * occurs very, very rare and, on the other hand, this situation is not
 * harmful for the application.
 *
 * <p><a href="MutexSync.java.html"><i>View Source</i></a></p>
 *
 * @version $Revision: 9 $ $Date: 2006-03-08 18:21:59 +0800 (星期三, 08 三月 2006) $
 */
public class MutexSync {

	private volatile Thread x;
	private volatile Thread y;
	/**
	 * Constructor.
	 */
	public MutexSync() {
		this.y = null;
		this.x = null;
	}

	public synchronized void lock() {
		Thread _current = Thread.currentThread();
		while (true) {
			this.x = _current;
			if (this.y != null) {
				Thread.yield();
				continue;
			}
			this.y = _current;
			if (this.x != _current) {
				Thread.yield();
				if (this.y != _current) {
					Thread.yield();
					continue;
				}
			}
			break;
		}
	}

	/**
	 * If Mutex is locked, returns false.
	 * If Mutex is unlocked, it locks it and returns true.
	 *
	 * @return true if mutex has been locked, false otherwise.
	 */
	public synchronized boolean lockTry() {
		if (isLocked() == true) {
			return false;
		}
		lock();
		return true;
	}

	public void unlock() {
		this.y = null;								// release mutex
	}

	public boolean isLocked() {
		return (null != this.y);
	}

}
